<template>
  <el-card class="page_card">
    <el-form :inline="true" class="form">
      <el-form-item label="角色名称：">
        <el-input v-model="data.keyword" placeholder="请输入角色名称"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="Search" color="#626aef" @click="search" 
          :disabled="data.keyword?false:true">搜索</el-button>
        <el-button @click="reset" color="#626aef" plain>重置</el-button>
      </el-form-item>
    </el-form>
    <el-button type="primary" icon="Plus" @click="addRole">添加角色</el-button>
    <el-table border :data="data.roleTableData" row-key="id" max-height="663">
      <el-table-column label="#" align="center" type="index" :width="80"></el-table-column>
      <el-table-column label="角色名称" align="center" prop="realName"></el-table-column>
      <el-table-column label="角色编码" align="center" prop="roleName"></el-table-column>
      <el-table-column label="操作" width="270px" align="center">
        <template #="{row}">
          <el-button type="primary" link icon="View" @click="viewOrUpdateRole(row,true)">查看</el-button>
          <el-button type="primary" link icon="Edit" @click="viewOrUpdateRole(row,false)">编辑</el-button>
          <el-popconfirm :title="`确认删除${row.realName}吗？`" width="240px" 
            @confirm="deleteRole(row)">
            <template #reference>
              <el-button type="danger" link icon="Delete">删除</el-button>
            </template>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
      v-model:current-page="data.currentPage"
      v-model:page-size="data.pageSize"
      :page-sizes="[10, 20, 30, 40]"
      :background="true"
      layout="->,prev, pager, next, jumper,sizes,total"
      :total="data.total"
      @current-change="currentChange"
      @size-change="sizeChange"
    />
  </el-card>
  <!-- 添加角色、更新角色 -->
  <el-dialog v-model="data.addRoleDialog" :title="data.roleForm.id?'更新角色':'添加角色'" width="650">
    <el-form :model="data.roleForm" :rules="data.rules" ref="formRef" label-width="130px" style="max-width: 550px">
      <el-form-item label="角色名称" prop="realName">
        <el-input v-model="data.roleForm.realName" placeholder="请输入角色名称"></el-input>
      </el-form-item>
      <el-form-item label="角色编码" prop="roleName">
        <el-input v-model="data.roleForm.roleName" placeholder="请输入角色编码" :disabled="data.roleForm.roleName == 'common_role'"></el-input>
      </el-form-item>
      <el-form-item label="菜单权限" prop="menuIcon" v-if="data.roleForm.roleName !== 'common_role'">
        <div class="form_tree">
          <el-tree
            ref="treeRef"
            highlight-current
            default-expand-all
            :data="data.mentTreeData"
            show-checkbox
            node-key="id"
            :props="data.defaultProps"
            :default-checked-keys="data.defaultKeys"
          />
        </div>
      </el-form-item>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="data.addRoleDialog = false">取消</el-button>
        <el-button type="primary" @click="save" :disabled="data.saveBtnDisabled">确定</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import {ref,onMounted,reactive,nextTick} from 'vue'
import {reqAllRole,reqAddOrUpdateRole,reqRemoveRole,reqGetMenuByRoleid,reqGetMenuByUserName} from '@/api/sys/roleApi'
import type { Role,RoleResData } from '@/api/sys/roleType'
import {reqAllMenu} from '@/api/sys/menuApi'
import type { MenuResData } from '@/api/sys/menuType'
import { ElMessage } from 'element-plus'
import useLayOutSettingStore from '@/store/modules/setting'
import {generateTree} from '@/utils/tools'
import { ElTree } from 'element-plus'
import useUserStore from '@/store/modules/user';
import { GET_USERINFO,SET_USERINFO } from "@/utils/token"; //本地存储方法

let userStore = useUserStore()
let settingStore = useLayOutSettingStore() // 模板setting仓库
let formRef = ref<any>() //form表单实例
const treeRef = ref<InstanceType<typeof ElTree>>()
const data = reactive({
  keyword:'',
  currentPage:1,
  pageSize:10,
  total:0,
  roleTableData:[] as Role[],
  addRoleDialog:false, //新增对话框
  roleForm:{ //新增表单
    realName:'', 
    roleName:'', 
    menuIds:'', 
    id:'',
  },
  mentTreeData:[] as Array<any>, //菜单树
  saveBtnDisabled:false,
  defaultMenuId:'', //首页菜单id
  defaultKeys:[] as Array<any>, //默认勾选首页
  defaultProps:{
    children: 'children',
    label: 'menuName',
    disabled: 'disabled',
  },
  rules:{
    realName:[{ required: true, trigger: 'blur', message:'请输入角色名称'}],
    roleName:[{ required: true, trigger: 'blur', message:'请输入角色编码'}],
  }
})

onMounted(() => {
  initRoleData()
  initMenuSelect()
})

// 菜单权限 树
const initMenuSelect = async() => {
  let res:MenuResData = await reqAllMenu()
  if(res.code==200){
    data.mentTreeData = generateTree(res.data.records)
    // 首页必选
    data.mentTreeData.find((item:any) => {
      if(item.menuId=='Home'){
        item.disabled = true
        data.defaultMenuId = item.id
        data.defaultKeys.push(item.id)
      }
    })
  }
}
// 搜索
const search = ()=>{
  initRoleData()
}
// 重置
const reset = ()=>{
  settingStore.refsh = !settingStore.refsh
}
// 分页器下拉事件
const currentChange = () => {
  initRoleData(data.currentPage)
}
const sizeChange = ()=> {
  initRoleData()
}
// 获取角色列表
const initRoleData = async(pager=1)=> {
  data.currentPage = pager
  let params = {
    current:data.currentPage,
    size:data.pageSize,
    name:data.keyword,
    active:'1', //1启用0未启用
  }
  let res:RoleResData = await reqAllRole(params)
  if(res.code==200){
    data.roleTableData = res.data.records
    data.total = res.data.total
  }
}
// 新增对话框
const addRole = ()=> {
  data.defaultKeys = [data.defaultMenuId]
  data.addRoleDialog = true
  treeRef.value?.setCheckedKeys([], false) //置空树勾选
  // 清空数据
  Object.assign(data.roleForm,{
    realName:'', 
    roleName:'', 
    menuIds:'', 
    id:'',
  })
  nextTick(() => {
    // 清除上一次错误提示信息
    formRef.value.clearValidate('realName')
    formRef.value.clearValidate('roleName')
  })
}
// 查看 / 编辑对话框
const viewOrUpdateRole = async(row:Role,disabled:boolean)=> {
  data.saveBtnDisabled = disabled
  data.addRoleDialog = true
  // 菜单权限树回显
  let res = await reqGetMenuByRoleid((row.id as number))
  let checkArr = res.data.map((item:any) => item.id)
  treeRef.value?.setCheckedKeys(checkArr)
  Object.assign(data.roleForm,row)
  nextTick(() => {
    // 清除上一次错误提示信息
    formRef.value.clearValidate('realName')
    formRef.value.clearValidate('roleName')
  })
}
// 新增/编辑确认
const save = async() => {
  try{
    await formRef.value.validate()
    if(treeRef.value){
      let checkNode = treeRef.value.getCheckedNodes()
      data.roleForm.menuIds = checkNode.map(item => item.id).join(',')
    }
    let res = await reqAddOrUpdateRole(data.roleForm)
    if(res.code==200){
      data.addRoleDialog = false
      ElMessage.success(data.roleForm.id?'更新成功！':'添加成功！')
      initRoleData()
      if(data.roleForm.id){ setUserMenuInfo() }
    }else{
      data.addRoleDialog = false
      ElMessage.error(data.roleForm.id?'更新失败！':'添加失败！')
    }
  }catch (error) {}
}
// 更新角色后，刷新本地存储的用户菜单权限
const setUserMenuInfo = async() => {
  let res = await reqGetMenuByUserName(userStore.username)
  if(res.code==200){
    let userInfo = GET_USERINFO()
    userInfo.menuList = res.data
    SET_USERINFO(userInfo) // 更新用户信息
  }
}

// 删除单行角色
const deleteRole = async(row:Role)=>{
  if(row.roleName == 'common_role'){
    ElMessage.warning('common_role角色不可删除！')
    return
  }
  let res = await reqRemoveRole((row.id as number),row.version)
  if(res.code==200){
    ElMessage.success('删除成功！')
    initRoleData()
  }else{
    ElMessage.error('删除失败！')
  }
}
</script>

<style scoped lang="scss">
.form_tree{
  width: 100%;
  height: auto;
  border-radius: 4px;
  border: 1px solid #dcdfe6;
  padding: 5px;
}
:deep(.el-checkbox__input.is-disabled.is-checked .el-checkbox__inner){
  background-color:#409eff;
  border-color:#409eff;
}
:deep(.el-checkbox__input.is-disabled.is-checked .el-checkbox__inner:after){
  border-color:#fff;
}
</style>


